function makeIterator(array) {
    const arr = array;
    let index = 0;
    return {
        next: function () {
            if (index < array.length) {
                return {
                    value: arr[index++],
                    done: false,
                };
            } else {
                return {
                    value: undefined,
                    done: true,
                };
            }
        },
    };
}

// test
// 最简单的迭代器结构
const arr = [1, 2, 3, 4, 5];
const iter = makeIterator(arr);
for (let i = 0; i < 10; i++) {
    const res = iter.next();
    console.log(JSON.stringify(res));
}

/**
 * 在类里定义迭代器
 */
class IteratorClass {
    constructor(arr) {
        this.arr = arr;
        this.arrIndex = 0;
    }

    [Symbol.iterator]() {
        return this;
    }

    next() {
        if (this.arrIndex < this.arr.length) {
            return {
                value: this.arr[this.arrIndex++],
                done: false,
            };
        } else {
            return {
                value: undefined,
                done: true,
            };
        }
    }
}

const ic = new IteratorClass([10, 20, 30, 40, 50]);
const ic_func = ic[Symbol.iterator]();
for (let i = 0; i < 10; i++) {
    const res = ic_func.next();
    console.log(JSON.stringify(res));
}

/**
 * 在对象里定义迭代器
 */

const obj = {
    index: 0,
    [Symbol.iterator]: function () {
        const self = this;
        return {
            next: function () {
                return self.index++;
            },
        };
    },
};

const obj_iter = obj[Symbol.iterator]();
for (let i = 0; i < 10; i++) {
    const res = obj_iter.next();
    console.log(JSON.stringify(res));
}

/**
 * 迭代器的中断
 * 设置一个迭代器，但这个迭代器可以被其中断函数中断
 */

function stopIterator(arr) {
    this.arr = arr;
    this.index = 0;
    this.cancelFlag = false;

    function funcCancel() {
        const self = this;
        self.cancelFlag = true;
    }

    function funcIterator() {
        const self = this;
        return {
            next: function () {
                if (self.cancelFlag) {
                    return { value: undefined, done: true };
                } else {
                    const ended = !(self.index < self.arr.length);

                    return {
                        value: ended ? undefined : self.arr[self.index++],
                        done: ended,
                    };
                }
            },
        };
    }

    return [funcCancel, funcIterator];
}

let [funcCancel, funcIterator] = stopIterator([1, 2]);
console.log(funcIterator().next());
funcCancel();
console.log(funcIterator().next());
console.log(funcIterator().next());
